﻿using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Threading;
using System.Globalization;

namespace Forging2.Common.Forging
{
    /// <summary>
    /// ForgingWindow.xaml 的交互逻辑
    /// </summary>
    public partial class ForgingWindow : Window
    {
        public ForgingWindow()
        {
            InitializeComponent();
        }

        private Thread thdDisplayStatus;
        private ForgingDevice ForgingDevice = new ForgingDevice();
        private bool IsCanOperated = false;

        private void InFurnace_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            /*
            Cursor = Cursors.Wait;
            JsonSerializer serializer = new JsonSerializer();
            using (var sr = new System.IO.StreamReader(AppDomain.CurrentDomain.BaseDirectory + @"\AppConfig.json"))
            {
                Const.Config = serializer.Deserialize(sr, typeof(AppConfig)) as AppConfig;
            }
            Heating.HeatingFurnace heatingfurnace = new Heating.HeatingFurnace("ddfd");
            dgInFurnace.ItemsSource = heatingfurnace.GetInFurnaceWorkpiece();
            dgOutFurnace.ItemsSource = heatingfurnace.GetOutFurnaceWorkpiece();
            Cursor = null;
            */
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            Binding binding = new Binding();
            binding.Source = Common.Const.Front;
            binding.Path = new PropertyPath("Notification");
            BindingOperations.SetBinding(txbNotification, TextBlock.TextProperty, binding);

            thdDisplayStatus = new Thread(SetSatuts) { IsBackground = true };
            thdDisplayStatus.Start();
            //await ForgingRun.ForgingOPC.OpenOPCServer();
            //opcUaClientServer = new Services.OPCService.OpcUaClientServer();
            ForgingOPC = new ForgingOPC();

        }
        private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            if (ForgingOPC.opcUaClient is null)
            {
                return;
            }
            ForgingOPC.opcUaClient.RemoveSubscription(Environment.MachineName);
            ForgingOPC.opcUaClient.Disconnect();
        }

        private void dgInFurnace_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (dgInFurnace.SelectedIndex + 1 == ((DataGrid)e.Source).Items.Count)
            {
                return;
            }
            var heatingworkpiece = (Heating.HeatingWorkpiece)dgInFurnace.SelectedItem;
            if (heatingworkpiece is null)
            {
                return;
            }
            App.Current.Dispatcher.BeginInvoke(new Action(() =>
            {
                txbClampingForgingNo.Text = heatingworkpiece.FORGING_NO;
                txbForgingNoArea.Text = heatingworkpiece.FURNACE_AREA;
                txbHeatingWrokpieceTemperatures.Text = heatingworkpiece.FURNACE_TEMPERATURES.ToString();
                txbForgingNo.Text = heatingworkpiece.FORGING_NO;                ;
            }));

        }

        private async void MountGuard_Click(object sender, RoutedEventArgs e)
        {
            Cursor = Cursors.Wait;
            if (MountGuard.Content.ToString() == "上岗")
            {
                Cursor = Cursors.Wait;
                txtOperatCode.Text = Const.Config.OperateCode;
                await ForgingOPC.opcUaClient.ConnectServer(Const.Config.ForgingOPCServerPath);
                ForgingOPC.SubscriptionValue(SubCallback);
                Const.Front.Notification = string.Format("检索到可选 {0} 条数据！", await ForgingDevice.LoadForgingOperateData());
                Task tk = ForgingDevice.LoadTadayForgingData();
                tk.Wait();
                tk = Task.Run(() => BindingDataGrid());
                await tk;
                dgOperabilityForging.SelectedIndex = 0;


                MountGuard.Content = "离岗";
                Const.Front.Notification = "上岗操作完成！";
                IsCanOperated = true;
            }
            else
            {
                ForgingOPC.opcUaClient.RemoveSubscription(Environment.MachineName);
                ForgingOPC.opcUaClient.Disconnect();
                MountGuard.Content = "上岗";
                Const.Front.Notification = "离岗操作完成！";
                IsCanOperated = false;
            }
            Cursor = null;

        }

        private void Furnace_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            DataGrid dg = sender as DataGrid;
            if (dg.SelectedIndex == -1)
            {
                return;
            }
            var dgr = dg.SelectedItem as DataBase.ZH_IMES.V_ForgingOperateData;
            txbClampingForgingNo.Text = dgr.ForgingNO;
            txbForgingNoArea.Text = dgr.FurnaceArea;
            //txbHeatingWrokpieceTemperatures.Text = heatingworkpiece.FURNACE_TEMPERATURES.ToString();
            txbForgingNo.Text = dgr.ForgingNO;

        }

        private void InFurnace_Click(object sender, RoutedEventArgs e)
        {

        }
        private void OutFurnace_Click(object sender, RoutedEventArgs e)
        {
            if (!IsCanOperated)
            {
                Const.Front.Notification = "请先上岗进行操作！";
                return;
            }

            string ret = "";
            var workpiece = Const.v_ForgingOperateDatas.Where(v => v.ForgingNO == txbClampingForgingNo.Text.Trim() && Const.Config.FurnaceWorkCells.Contains(v.WORKCELL_CODE)).FirstOrDefault();
            if (workpiece is null)
            {
                ret = "无相关的锻件信息，不能进行出炉操作！";
                Const.Front.Notification = ret;
                return;
            }
            Heating.HeatingFurnace heatfurnace = Const.HeatingFurnaces.Where(h => h.MESCODE == workpiece.WORKCELL_CODE).FirstOrDefault() as Heating.HeatingFurnace;
            var wp = Const.WorkPieceDBToWorkpice(workpiece, null);
            Task<dynamic> t = heatfurnace.OutFurnace(wp);
            t.Wait();
            ret = t.Result;
            Const.Front.Notification = ret;
            Task tk = new Task(() => BindingDataGrid());
            tk.RunSynchronously();
            //t.Start();
            //tk.Wait();
        }

        private async void btnForging_Click(object sender, RoutedEventArgs e)
        {
            if (!IsCanOperated)
            {
                Const.Front.Notification = "请先上岗进行操作！";
                return;
            }
            WorkingPiece workpiece = new WorkingPiece()
            {
                ForgingNO = txbForgingNo.Text.Trim(),
                OutFurnaceTemperatures = int.Parse(txbHeatingWrokpieceTemperatures.Text),
                WorkpieceHeight = int.Parse(txbCurrentHeight.Text),
                WorkpieceTemperatures = int.Parse(txbHeatingWrokpieceTemperatures.Text),
                Operater = txtOperatCode.Text
            };
            try
            {
                Task<dynamic> t = ForgingDevice.ForgingBeging(workpiece);
                dynamic msg = await t;
                Const.Front.Notification = msg;
                Console.WriteLine(Const.ZH_IMESDbContext.SaveChanges());
                Task<int> td = ForgingDevice.LoadForgingOperateData();
                td.Wait();
                td = ForgingDevice.LoadTadayForgingData();
                td.Wait();
                Task tk = new Task(() => BindingDataGrid());
                tk.RunSynchronously();
                //await tk;
                //MessageBox.Show(s);
                string s = string.Format("{0}  {1} {2} KG", workpiece.ForgingNO, workpiece.PRODU_NAME, workpiece.PROCESS_WEIGHT.ToString());
                SendDisplayLED(s);

            }
            catch (Exception ex)
            {
                Const.Front.ErrorNotification = ex.Message.ToString();
                AppLog.WriteErrorLog(string.Format("Class: {0}, Error: {1}", ex.GetType().FullName, ex.Message.ToString()));
            }
        }



        private async void btnFinshed_Click(object sender, RoutedEventArgs e)
        {
            if (!IsCanOperated)
            {
                Const.Front.Notification = "请先上岗进行操作！";
                return;
            }
            WorkingPiece workpiece = new WorkingPiece()
            {
                ForgingNO = txbForgingNo.Text.Trim(),
                OutFurnaceTemperatures = int.Parse(txbHeatingWrokpieceTemperatures.Text),
                WorkpieceHeight = int.Parse(txbCurrentHeight.Text),
                WorkpieceTemperatures = int.Parse(txbHeatingWrokpieceTemperatures.Text),
                Operater = txtOperatCode.Text,
            };
            try
            {
                Const.Front.Notification = await ForgingDevice.ForgingFinshed(workpiece);
                Task<int> td = ForgingDevice.LoadForgingOperateData();
                td.Wait();
                td = ForgingDevice.LoadTadayForgingData();
                td.Wait();
                Task tk = new Task(() => BindingDataGrid());
                tk.RunSynchronously();
            }
            catch (Exception ex)
            {
                Const.Front.ErrorNotification = ex.Message.ToString();
                AppLog.WriteErrorLog(string.Format("Class: {0}, Error: {1}", ex.GetType().FullName, ex.Message.ToString()));

            }
        }
        private void btnZeroSetting_Click(object sender, RoutedEventArgs e)
        {
            if (!IsCanOperated)
            {
                Const.Front.Notification = "请先上岗进行操作！";
                return;
            }
            txbBaseHeight.Text = txbRealHeight.Text;
            try
            {
                SetZeroHeight(int.Parse(txbBaseHeight.Text), int.Parse(txbFixHeight.Text), int.Parse(txbMinHeight.Text));
            }
            catch (Exception ex)
            {
                AppLog.WriteErrorLog(string.Format("Class: {0}, Error: {1}", ex.GetType().FullName, ex.Message.ToString()));                
            }
            
        }
        private void dgOperabilityForging_Selected(object sender, RoutedEventArgs e)
        {
            var dg = (DataGrid)sender;
            if (dg.SelectedIndex == -1)
            {
                return;
            }
            //DataBase.ZH_IMES.V_ForgingOperateData dgr = dg.SelectedItem as DataBase.ZH_IMES.V_ForgingOperateData;
            //var dgr = dg.SelectedItem as ForgingOperateRecord;
            try
            {
                txbClampingForgingNo.Text = dg.SelectedItem.ToString().Split(',')[0].Split('=')[1].Trim();
                txbForgingNo.Text = dg.SelectedItem.ToString().Split(',')[0].Split('=')[1].Trim();
            }
            catch (Exception ex)
            {
                AppLog.WriteErrorLog(string.Format("Class: {0}, Error: {1}", ex.GetType().FullName, ex.Message.ToString()));
                throw;
            }
            





        }

        private void txbBaseHeight_TextChanged(object sender, TextChangedEventArgs e)
        {
            if (string.IsNullOrEmpty(txbBaseHeight.Text) || txbMinHeight is null || string.IsNullOrEmpty(txbMinHeight.Text))
            {
                return;
            }
            txbMinHeight.Text = (int.Parse(txbBaseHeight.Text) + Const.Config.ForgingSetSpan).ToString();

        }

        private void SetSatuts()
        {
            bool bl = false;
            while (true)
            {
                if (bl)
                {
                    App.Current.Dispatcher.Invoke(new Action(() => { Satuts.Fill = ForgingOPC.opcUaClient.Connected ? new SolidColorBrush(Colors.Green) : new SolidColorBrush(Colors.Red); }));
                    System.Threading.Thread.Sleep(1500);
                }
                else
                {
                    Application.Current.Dispatcher.Invoke(new Action(() => { Satuts.Fill = new SolidColorBrush(Colors.Transparent); }));
                    Thread.Sleep(1000);
                }
                bl = !bl;

            }
        }



        private ForgingOPC ForgingOPC;
        private void SubCallback(string key, Opc.Ua.Client.MonitoredItem monitoredItem, Opc.Ua.Client.MonitoredItemNotificationEventArgs args)
        {
            if (key != Environment.MachineName)
            {
                Const.Front.Notification = "机器名不匹配，订阅失败！";
                return;
            }
            try
            {
                Opc.Ua.MonitoredItemNotification notification = args.NotificationValue as Opc.Ua.MonitoredItemNotification;
                if (Opc.Ua.DataValue.IsGood(notification.Value))
                {
                    //基准值
                    if (monitoredItem.StartNodeId.ToString() == ForgingOPC.BaseHeight)
                    {
                        //Const.Front.ForgingBaseHeight = notification.Value.WrappedValue.Value.ToString();
                        Application.Current.Dispatcher.Invoke(new Action(() => { txbBaseHeight.Text = notification.Value.WrappedValue.Value.ToString(); }));
                    }
                    if (monitoredItem.StartNodeId.ToString() == ForgingOPC.CurrentHeight)
                    {
                        //Const.Front.ForgingCurrentHeight = notification.Value.WrappedValue.Value.ToString();
                        Application.Current.Dispatcher.Invoke(new Action(() => { txbCurrentHeight.Text = notification.Value.WrappedValue.Value.ToString(); }));
                    }
                    if (monitoredItem.StartNodeId.ToString() == ForgingOPC.FixHeight)
                    {
                        //Const.Front.ForgingFixHeight = notification.Value.WrappedValue.Value.ToString();
                        Application.Current.Dispatcher.Invoke(new Action(() => { txbFixHeight.Text = notification.Value.WrappedValue.Value.ToString(); }));
                    }
                    if (monitoredItem.StartNodeId.ToString() == ForgingOPC.opcMinHeight)
                    {
                        //Const.Front.ForgingMinHeight = notification.Value.WrappedValue.Value.ToString();
                        Application.Current.Dispatcher.Invoke(new Action(() => { txbMinHeight.Text = notification.Value.WrappedValue.Value.ToString(); }));
                    }
                    if (monitoredItem.StartNodeId.ToString() == ForgingOPC.RealHeight)
                    {
                        //Const.Front.ForgingRealHeight = notification.Value.WrappedValue.Value.ToString();
                        Application.Current.Dispatcher.Invoke(new Action(() => { txbRealHeight.Text = notification.Value.WrappedValue.Value.ToString(); }));
                    }
                    if (monitoredItem.StartNodeId.ToString() == ForgingOPC.WorkpieceHeight)
                    {
                        //Const.Front.ForgingWorkpieceHeight = notification.Value.WrappedValue.Value.ToString();
                        Application.Current.Dispatcher.Invoke(new Action(() => { txbWorkpieceHeight.Text = notification.Value.WrappedValue.Value.ToString(); }));
                    }
                    if (monitoredItem.StartNodeId.ToString() == ForgingOPC.Temperatures1)
                    {
                        //Const.Front.ForgingTemperatures1 = notification.Value.WrappedValue.Value.ToString();
                        Application.Current.Dispatcher.Invoke(new Action(() => { txbTemperatures1.Text = notification.Value.WrappedValue.Value.ToString(); }));
                    }
                    if (monitoredItem.StartNodeId.ToString() == ForgingOPC.Temperatures2)
                    {
                        //Const.Front.ForgingTemperatures2 = notification.Value.WrappedValue.Value.ToString();
                        Application.Current.Dispatcher.Invoke(new Action(() => { txbTemperatures2.Text = notification.Value.WrappedValue.Value.ToString(); }));
                    }
                    //选择信号
                    if (monitoredItem.StartNodeId.ToString() == ForgingOPC.SelectSignal)
                    {
                        if ((bool)notification.Value.WrappedValue.Value)
                        {
                            Application.Current.Dispatcher.Invoke(()=> SelectWorkpiece());
                        }

                    }
                    //锻压信号
                    if (monitoredItem.StartNodeId.ToString() == ForgingOPC.ForgingSignal)
                    {
                        if ((bool)notification.Value.WrappedValue.Value)
                        {
                            //btnForging_Click(btnForging, new RoutedEventArgs());
                            //AnalysisForging();
                            Application.Current.Dispatcher.Invoke(() => btnForging.RaiseEvent(new RoutedEventArgs(Button.ClickEvent)));
                            //btnForging.RaiseEvent(new RoutedEventArgs(Button.ClickEvent));
                        }
                    }
                    //归零信号
                    if (monitoredItem.StartNodeId.ToString() == ForgingOPC.ZeroSignal)
                    {
                        if ((bool)notification.Value.WrappedValue.Value)
                        {
                            //btnZeroSetting_Click(btnZeroSetting, new RoutedEventArgs());
                            //btnZeroSetting.RaiseEvent(new RoutedEventArgs(Button.ClickEvent));
                            Application.Current.Dispatcher.Invoke(() => btnZeroSetting.RaiseEvent(new RoutedEventArgs(Button.ClickEvent)));

                        }

                    }
                    //完工信号
                    if (monitoredItem.StartNodeId.ToString() == ForgingOPC.ForgingFinshedSignal)
                    {
                        if ((bool)notification.Value.WrappedValue.Value)
                        {
                            //btnFinshed_Click(btnFinshed, new RoutedEventArgs());
                            Application.Current.Dispatcher.Invoke(() => btnFinshed.RaiseEvent(new RoutedEventArgs(Button.ClickEvent)));
                            //btnFinshed.RaiseEvent(new RoutedEventArgs(Button.ClickEvent));
                        }

                    }


                    //Console.WriteLine(notification.Value.WrappedValue.Value.ToString());
                }

            }
            catch (Exception ex)
            {
                AppLog.WriteErrorLog(string.Format("Class: {0}, Error: {1}", ex.GetType().FullName, ex.Message.ToString()));
                throw;
            }
            
        }

        private void ForgingSubscription()
        {
            ForgingOPC.SubscriptionValue(SubCallback);
        }

        private async void SetZeroHeight(int BaseValue, int FixValue, int LimitValue)
        {
            OpcUaHelper.OpcNodeAttribute bNode = new OpcUaHelper.OpcNodeAttribute() { Name = ForgingOPC.BaseHeight, Value = BaseValue };
            OpcUaHelper.OpcNodeAttribute fNode = new OpcUaHelper.OpcNodeAttribute() { Name = ForgingOPC.FixHeight, Value = FixValue };
            OpcUaHelper.OpcNodeAttribute lNode = new OpcUaHelper.OpcNodeAttribute() { Name = ForgingOPC.opcMinHeight, Value = LimitValue };
            Const.Front.Notification = await ForgingDevice.ForgingSetZero(ForgingOPC.opcUaClient, bNode, fNode, lNode);

        }

        private void SelectWorkpiece()
        {
            if (dgOperabilityForging.SelectedIndex == -1)
            {
                dgOperabilityForging.SelectedIndex = 0;
                return;
            }
            int idx = dgOperabilityForging.SelectedIndex < dgOperabilityForging.Items.Count - 1 ? ++dgOperabilityForging.SelectedIndex : 0;
            dgOperabilityForging.SelectedIndex = idx;
            Console.WriteLine(string.Format("SelectedIndex: ", idx));
        }

        private void BindingDataGrid()
        {
            var furances = Const.Config.FurnaceWorkCells.ToArray();
            Application.Current.Dispatcher.Invoke(new Action(() => dgInFurnace.ItemsSource = Const.v_ForgingOperateDatas.Where(d => d.InFurnace == "1" && d.OUT_TIME is null)));
            Application.Current.Dispatcher.Invoke(new Action(() => dgOutFurnace.ItemsSource = Const.v_ForgingOperateDatas.Where(d => d.InFurnace == "0" && furances.Contains(d.WORKCELL_CODE))));
            Application.Current.Dispatcher.Invoke(new Action(() => dgOperabilityForging.ItemsSource = Const.v_ForgingOperateDatas.Select(s => new
            {
                s.ForgingNO,
                s.PRODU_CODE,
                s.PRODU_NAME,
                s.PRODU_SIZE,
                s.MakingLotNo,
                s.PROCESS_WEIGHT,
                s.ORDER_WEIGHT,
                s.PORCESS_COMBINE
            }).Distinct().OrderBy(s => s.ForgingNO)));
            Application.Current.Dispatcher.Invoke(new Action(() => dgTadayForginged.ItemsSource = Const.v_WorkRecords));

            Application.Current.Dispatcher.Invoke(new Action(() =>
            {
                txbDataCount.Text = string.Format("在炉件数： {0}  炉外件数： {1} 可操作数： {2} ", dgInFurnace.Items.Count, dgOutFurnace.Items.Count, dgOperabilityForging.Items.Count);
                txbDataCount.Visibility = Visibility.Visible;
            }));
        }


        private void SendDisplayLED(string LEDtxt)
        {
            try
            {
                System.IO.File.WriteAllText(Const.Config.LEDFile, LEDtxt);
            }
            catch (Exception ex)
            {
                var s = string.Format("Class {0} ; Error {1} ", ex.GetType().FullName, ex.Message.ToString());
                Const.Front.ErrorNotification = s;
                Console.WriteLine(s);
                throw;
            }
        }

        private void btnTest_Click(object sender, RoutedEventArgs e)
        {
            //MessageBox.Show("Test");
            var frm = new ControlPanel();
            frm.Show();
            frm.Owner = this;

        }

       
    }
}
